package tc.oc.commons.bukkit.chat; import javax.inject.Inject; import javax.inject.Singleton; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.inject.ConfigurationException; import com.google.inject.Injector; import com.google.inject.Key; import net.md_5.bungee.api.chat.BaseComponent; import org.bukkit.command.CommandSender; @Singleton public class ComponentRendererRegistry implements ComponentRenderContext { private final Injector injector; private final LoadingCache<Class<? extends BaseComponent>, ComponentRenderer> renderers = CacheBuilder.newBuilder().build(new CacheLoader<Class<? extends BaseComponent>, ComponentRenderer>() { @Override public ComponentRenderer load(final Class<? extends BaseComponent> type) throws Exception { ConfigurationException originalException = null; for(Class c = type; BaseComponent.class.isAssignableFrom(c); c = c.getSuperclass()) { try { return (ComponentRenderer) injector.getInstance(Key.get(ComponentRenderers.rendererType(c))); } catch(ConfigurationException e) { if(originalException == null) originalException = e; } } throw new IllegalStateException("Can't find a renderer for component type " + type, originalException); } }); @Inject ComponentRendererRegistry(Injector injector) { this.injector = injector; } public <T extends BaseComponent> ComponentRenderer<? super T> getRenderer(T component) { return (ComponentRenderer<? super T>) renderers.getUnchecked(component.getClass()); } @Override public BaseComponent render(BaseComponent component, CommandSender viewer) { if(component instanceof RenderableComponent) { return ((RenderableComponent) component).render(this, viewer); } ComponentRenderer renderer = getRenderer(component); if(renderer != null) { return renderer.render(this, component, viewer); } return component; } }